package dominio.ubicaciones

import com.fasterxml.jackson.annotation.JsonIgnore
import dominio.datos.Caracteristica
import dominio.individuos.CuidadorAjeno
import dominio.individuos.CuidadorEnTrampa
import dominio.individuos.Informante
import dominio.investigacion.Caso
import dominio.investigacion.Mapamundi
import java.util.ArrayList
import java.util.List
import org.uqbar.commons.model.ObservableUtils
import org.uqbar.commons.model.UserException
import org.uqbar.commons.utils.Observable

@Observable
class Pais {
	
	private String nombre
	@JsonIgnore private Caso caso;
	@Property List<Lugar> lugares
	@Property List<Caracteristica> caracteristicas 
	@JsonIgnore private List<Pais> conexiones
	
	@Property List<String> nombresConexiones
	
	@JsonIgnore	private Mapamundi mapamundi
	@Property boolean tieneNombreValido
	
	new() {
		this.lugares = new ArrayList<Lugar>
		this.caracteristicas = new ArrayList<Caracteristica>
		this.conexiones = new ArrayList<Pais>
		this.nombresConexiones = new ArrayList<String>
		this.tieneNombreValido = false
	}
	
	@JsonIgnore
	def Caso getCaso() {
		this.caso
	}
	
	@JsonIgnore
	def void setCaso(Caso caso) {
		this.caso = caso
	}
	
	@JsonIgnore
	def Mapamundi getMapamundi() {
		this.mapamundi
	}
	
	@JsonIgnore
	def void setMapamundi(Mapamundi mapamundi) {
		this.mapamundi = mapamundi
	}
	
	@JsonIgnore
	def List<Pais> getConexiones() {
		this.conexiones
	}
	
	@JsonIgnore
	def void setConexiones(List<Pais> conexiones) {
		this.conexiones = conexiones
	}
	
	new(String nombre) {
		new Pais => [ it.nombre = nombre ]
	}
	
	def getNombre() {
		this.nombre
	}
	
	def setNombre(String nombre) {
		this.nombre = nombre
		tieneNombreValido = esNombreValido
		ObservableUtils.firePropertyChanged(this,"nombre", nombre)
		ObservableUtils.firePropertyChanged(this, "tieneNombreValido", tieneNombreValido)
	}
	
	def siguientePais(){
		caso.siguiente(this)
	}
	
	def eliminarConexion(Pais pais) {
		pais.conexiones.remove(this)
		conexiones.remove(pais)
		ObservableUtils.firePropertyChanged(this,"conexiones", conexiones)
		ObservableUtils.firePropertyChanged(pais,"conexiones", pais.conexiones)
	}
	
	def agregarConexion(Pais pais) {
		conexiones += pais
		pais.conexiones += this
		nombresConexiones += pais.nombre
		pais.nombresConexiones += this.nombre
		ObservableUtils.firePropertyChanged(this, "conexiones", conexiones)
		ObservableUtils.firePropertyChanged(pais, "conexiones", pais.conexiones)
	}
	
	def agregarLugar(Lugar lugar) {
		if(lugares.size < 3) lugares += lugar
		else throw new UserException("Solo puede tener 3 (tres) lugares")
		ObservableUtils.firePropertyChanged(this, "lugares", lugares)
	}
	
	def tieneLosLugaresRequeridos() {
		lugares.size == 3
	}
	
	def esNombreValido() {
		nombre = nombre.trim
		nombre.length > 0
		
	}
	
	def mismoPais(Pais pais) {
		this.nombre == pais.nombre
	}
	
	def setearInformantes() {
		lugares.forEach[l | l.ocupante = new Informante(l)]
	}
	
	def setearCuidadores() {
		lugares.forEach[l | l.ocupante = new CuidadorAjeno]
	}
	
	def setearVillano() {
		
		var randomIndex = (Math.random*(lugares.size - 1)).intValue
		lugares.get(randomIndex).ocupante = caso.responsable
		lugares.forEach[l | if(l.ocupante == null) l.ocupante = new CuidadorEnTrampa]
	}
	
	def borrarConexion(Pais pais) {
		this.conexiones.remove(pais)
	}
	
}